﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace MongoExplorerTool.Infra.Connection
{
    public class Manager
    {
        #region Constants
        private const string CONFIG_FILE_NAME = "MongoExplorerToolConfig.xml";
        #endregion Constants

        #region Variables
        private readonly string _configFilePath;
        private List<ConnectionInfo> _connections;
        #endregion Variables

        #region Constructors
        public Manager()
        {
            this._configFilePath = string.Format(@"{0}\{1}", AppDomain.CurrentDomain.BaseDirectory, CONFIG_FILE_NAME);
            if (!System.IO.File.Exists(this._configFilePath))
                this.SaveXml(this._connections);
            else
                this._connections = this.LoadXml();
        }
        #endregion Constructors

        #region Methods
        public ConnectionInfo Create(ConnectionInfo connectionInfo)
        {
            if (connectionInfo == null)
                throw new InvalidConnectionInfoException();

            if(!connectionInfo.IsValid())
                throw new InvalidConnectionInfoException();

            var existentConnection = this.GetByName(connectionInfo.Name);
            if (existentConnection != null)
                throw new AlreadyExistingConnectionException();

            if (this._connections == null)
                this._connections = new List<ConnectionInfo>();
            this._connections.Add(connectionInfo);
            this.SaveXml(this._connections);

            return connectionInfo;
        }

        public void DeleteByName(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
                throw new ArgumentNullException("name");

            var newConnections = this._connections.Where(c => !c.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)).ToList();
            this.SaveXml(newConnections);
            this._connections = this.LoadXml();
        }

        public ConnectionInfo GetByName(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
                throw new ArgumentNullException("name");

            if (this._connections == null)
                return null;

            return this._connections.FirstOrDefault(c => c.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
        }

        public List<ConnectionInfo> List()
        {
            return this._connections;
        }

        private List<ConnectionInfo> LoadXml()
        {
            if (!System.IO.File.Exists(this._configFilePath))
                return null;

            XmlSerializer deserializer = new XmlSerializer(typeof(List<ConnectionInfo>));
            TextReader textReader = new StreamReader(this._configFilePath);
            var connections = deserializer.Deserialize(textReader) as List<ConnectionInfo>;
            textReader.Close();

            return connections;
        }

        private void SaveXml(List<ConnectionInfo> connections)
        {
            if (System.IO.File.Exists(this._configFilePath))
                System.IO.File.Delete(this._configFilePath);

            XmlSerializer serializer = new XmlSerializer(typeof(List<ConnectionInfo>));
            TextWriter textWriter = new StreamWriter(this._configFilePath);
            serializer.Serialize(textWriter, connections);
            textWriter.Close();
        }
        #endregion Methods
    }
}
